package com.lagou.edu.factory;

import com.lagou.edu.annotation.Autowired;
import com.lagou.edu.annotation.Service;
import com.lagou.edu.utils.TransactionManager;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 代理工厂
 *  为被代理对象添加事物控制（使用AOP思想 1为业务逻辑前后添加事物开启、事物提交，2捕获异常 异常时回滚事物）
 */
@Service()
public class ProxyFactory {
    @Autowired
    private TransactionManager transactionManager;

    public void setTransactionManager(TransactionManager transactionManager){
        this.transactionManager = transactionManager;
    }
    public Object getProxy(Object object){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), object.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object result = null;
                try{
                    transactionManager.beginTransaction();//开启事物
                    method.invoke(object,args); // 执行业务逻辑
                    transactionManager.commit(); //提交事物
                }catch (Exception e){
                    e.printStackTrace();
                    transactionManager.rollback();
                    throw e.getCause(); // 异常捕获抛出，便于servlet中捕获
                }
                return result;
            }
        });
    }
    // cjlib代理
    public Object getCjlbProxy(Object o){
        return Enhancer.create(o.getClass(), new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                Object result = null;
                try{
                    transactionManager.beginTransaction();//开启事物
                    method.invoke(o,objects); // 执行业务逻辑
                    transactionManager.commit(); //提交事物
                }catch (Exception e){
                    e.printStackTrace();
                    transactionManager.rollback();
                    throw e.getCause(); // 异常捕获抛出，便于servlet中捕获
                }
                return result;
            }
        });
    }
}
